import importlib.util
import os
import shutil
import unittest
import uuid
import requests
from flask import jsonify
from Base.BaseSettings import TestDataDIR
from Common.utils import apk_utils

# 任务配置信息
AirTaskData = {
    "package_path": "",
    "package_name": ""
}


def download(url, file_name=f"{uuid.uuid4()}.apk", directory=TestDataDIR):
    """
    下载网络地址的文件
    :param url: 下载地址
    :param file_name: 下载后的文件名称
    :param directory: 下载目录
    :return: 返回文件路径
    """
    try:
        # 确保目录存在，如果不存在则创建
        os.makedirs(directory, exist_ok=True)

        # 构造文件的完整路径
        file_path = os.path.join(directory, file_name)

        # 发送GET请求下载文件
        response = requests.get(url, stream=True)
        if response.status_code == 200:
            with open(file_path, 'wb') as file:
                # 以二进制写模式打开文件，并逐块写入
                for chunk in response.iter_content(chunk_size=1024):
                    if chunk:
                        file.write(chunk)
            print(f"文件 {file_name} 下载完成")
            package_name = None
            if file_name.endswith('.apk'):
                package_name = apk_utils.get_package_name(file_path)
            elif file_name.endswith('.ipa'):
                pass
            return file_path, package_name  # 返回文件路径, 包名
        else:
            print(f"下载失败，状态码: {response.status_code}")
    except requests.RequestException as e:
        print(f"下载出错: {e}")


def delete_file(file_path):
    """
    删除文件
    :param file_path:
    :return:
    """
    os.remove(file_path)


def delete_files_or_directory(directory):
    for filename in os.listdir(directory):
        file_path = os.path.join(directory, filename)
        if os.path.isfile(file_path):
            os.remove(file_path)
            print(f"DeletedFile: {file_path}")
        else:
            shutil.rmtree(file_path)
            print(f"DeletedDir: {file_path}")


def del_local_report():
    """
    删除测试报告文件夹
    :return:
    """
    from Base.BaseSettings import LogsDIR, ReportDIR, SuiteReport
    delete_files_or_directory(LogsDIR)
    delete_files_or_directory(ReportDIR)
    delete_files_or_directory(SuiteReport)


def get_str_time():
    """
    获取当前字符串时间：2024-01-03-18-29-34
    :return:
    """
    from datetime import datetime
    # 获取当前时间日期
    current_time = datetime.now()
    # 指定格式化字符串
    return current_time.strftime('%Y-%m-%d-%H-%M-%S')


def exec_airtest_suite(report_desc='') -> str:
    """
    执行测试套件，返回测试报告地址路径
    :param package_name: 测试包名
    :param report_desc: 报告描述信息
    :return: 测试报告地址路径
    """
    from Base.BaseSettings import SuiteReport, ServeSuiteReport
    from Base.BeautifulLib import DIYBeautifulReport

    suite = unittest.TestSuite()
    testCase = unittest.TestLoader().loadTestsFromTestCase(get_class_from_package(AirTaskData["package_name"]))
    suite.addTests(testCase)

    filename = f"{get_str_time()}.html"
    runner = DIYBeautifulReport(suite)
    runner.report(report_desc, filename, report_dir=SuiteReport)

    # 获取测试结果 - 当前不可用
    total_tests = runner.fields.get("testAll")
    # total_failures = runner.fields.get("testAll")
    # total_errors = runner.fields.get("testError")
    total_success = runner.fields.get("testPass")

    # 计算通过率
    pass_rate = (total_success / total_tests) * 100

    # print(f"Total tests: {total_tests}")
    # print(f"Pass: {total_success}")
    # print(f"Failures: {total_failures}")
    # print(f"Errors: {total_errors}")
    # print(f"Pass rate: {pass_rate:.2f}%")
    return fr'{ServeSuiteReport}{filename}', f"{pass_rate:.2f}"


def import_classes_from_case(class_name):
    from Base.BaseSettings import TestCaseDIR
    """
    通过字符串类名获取类
    :param class_name: 替换为你要获取的类名
    :return:
    """
    for dir_path, dir_names, filenames in os.walk(TestCaseDIR):
        for file in filenames:
            if file == f"{class_name}.py":
                module_name = file[:-3]
                module_path = os.path.join(dir_path, file)
                spec = importlib.util.spec_from_file_location(module_name, module_path)
                module = importlib.util.module_from_spec(spec)
                spec.loader.exec_module(module)

                try:
                    class_obj = getattr(module, class_name)
                    return class_obj
                except AttributeError:
                    print(f"Class '{class_name}' not found in module '{module_name}'")
                    return None


def get_classname_from_package(package_name) -> str:
    """
    根据APK包名获取CASE类名称
    :param package_name:
    :return: case_class_name
    """
    return "".join([item.capitalize() for item in package_name.split('.')[1:]])


def get_class_from_package(package_name):
    """
    通过包名获取类对象
    :param package_name: 包名：com.baidu.test
    :return: 类对象
    """
    classname = get_classname_from_package(package_name)
    print('调用的类名:', classname)
    return import_classes_from_case(classname)


# 响应值模板
def R(data=None, code=0, msg="success"):
    response = {
        'code': code,
        'msg': msg,
        'data': data
    }
    return jsonify(response)


if __name__ == '__main__':
    del_local_report()
    pass
